#include "stdfx.h"
XMMATRIX cubeWorld;
XMMATRIX projection;
double rot = 0;
int WINAPI WinMain(HINSTANCE hInstance,    //Main windows function
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nShowCmd)
{
	//HINSTANCE hInstance,
	//	const wstring WndClassName,
	//	int ShowWnd,
	//	int width,
	//	int height,
	//	bool windowed) :
	dx11App app(hInstance,
		L"packed-app",
		nShowCmd,
		800, 600,
		true);
	if (app.InitializeDirect3d11App())
	{
		app.MsgLoop();
	}
	return 0;
}
int dx11App::MsgLoop()
{
	MSG msg;
	ZeroMemory(&msg, sizeof(MSG));
	while (true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else {
			// run game code    
			if (!mAppPaused)
			{
				timer.Update();
				DetectInput();
				Update();
				Draw();
			}
		}
	}
	return msg.wParam;
}
void dx11App::Draw()
{
	float bgColor[4];
	ZeroMemory(&bgColor, sizeof(float) * ARRAYSIZE(bgColor));
	d3d11DevCon->ClearRenderTargetView(RenderTargetView.Get(), bgColor);
	d3d11DevCon->ClearDepthStencilView(DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
	d3d11DevCon->OMSetDepthStencilState(NULL, 0);
	
	//Reset Vertex and Pixel Shaders
	d3d11DevCon->VSSetShader(VS.Get(), 0, 0);
	d3d11DevCon->PSSetShader(PS.Get(), 0, 0);

	//Set our Render Target
	d3d11DevCon->OMSetRenderTargets(1, RenderTargetView.GetAddressOf(), DepthStencilView.Get());

	//Set the default blend state (no blending) for opaque objects
	d3d11DevCon->OMSetBlendState(0, 0, 0xffffffff);

	//Set the cubes index buffer
	d3d11DevCon->IASetIndexBuffer(IndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
	//Set the cubes vertex buffer
	UINT stride = sizeof(Vertex);
	UINT offset = 0;
	d3d11DevCon->IASetVertexBuffers(0, 1, VertexBuffer.GetAddressOf(), &stride, &offset);

	//Set the PVW matrix and send it to the constant buffer in effect file
	cbPerObjectVar.World = cubeWorld;
	cbPerObjectVar.PVW = projection*camera.camView*cubeWorld;
	d3d11DevCon->UpdateSubresource(cbPerObjectBuffer.Get(), 0, NULL, &cbPerObjectVar, 0, 0);
	d3d11DevCon->VSSetConstantBuffers(0, 1, cbPerObjectBuffer.GetAddressOf());
	cbPerFrameVar.light = light;
	d3d11DevCon->UpdateSubresource(cbPerFrameBuffer.Get(), 0, NULL, &cbPerFrameVar, 0, 0);
	d3d11DevCon->PSSetConstantBuffers(1, 1, cbPerFrameBuffer.GetAddressOf());

	d3d11DevCon->PSSetShaderResources(0, 1, ShaderResourceView.GetAddressOf());
	d3d11DevCon->PSSetSamplers(0, 1, CubesTexSamplerState.GetAddressOf());
	d3d11DevCon->RSSetState(DefaultRS.Get());

	D3D11_VIEWPORT viewport;
	ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

	viewport.TopLeftX = 0;
	viewport.TopLeftY = 0;
	viewport.Width = Width;
	viewport.Height = Height;
	viewport.MinDepth = 0.0f;
	viewport.MaxDepth = 1.0f;

	//Set the Viewport
	d3d11DevCon->RSSetViewports(1, &viewport);

	d3d11DevCon->DrawIndexed(36, 0, 0);

	//RenderText(L"", timer.fps);

	//Present the backbuffer to the screen
	SwapChain->Present(0, 0);
}
void dx11App::Update()
{
	static XMMATRIX Rotation, Translation, Scale;
	//Keep the cubes rotating
	//rot += 1.0f * timer.frameTime;
	if (rot > 6.28f)
		rot = 0.0f;
	cubeWorld = XMMatrixIdentity();
	//Define cube1's world space matrix
	XMVECTOR rotaxis = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
	Rotation = XMMatrixTranspose(XMMatrixRotationAxis(rotaxis, rot));
	Translation = XMMatrixTranspose(XMMatrixTranslation(0.0f, 3.0f, 0.0f));
	//Scale = XMMatrixTranspose(XMMatrixScaling(13.0f, 13.0f, 13.0f));
	cubeWorld = Rotation * Translation;
	projection = XMMatrixPerspectiveFovLH(0.4f*3.14f, (float)Width / Height, 1.0f, 1000.0f);
}